﻿using WPF.Core.Dtos;
using WPF.Core.Models;
using Prism.Ioc;

namespace WPF.Core.Services
{
    public class BaseService<T, F> where T : BaseModel where F : BaseTable
    {
        public BaseService()
        {
            mapper = ContainerLocator.Container.Resolve<IAppMapper>();
        }

        //FreeSql的静态数据库对象
        static Lazy<IFreeSql> sqliteLazy = new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
                .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=freedb.db")
                .UseAutoSyncStructure(true)
                .Build());

        public readonly IAppMapper mapper;

        public static IFreeSql Sqlite => sqliteLazy.Value;

        /// <summary>
        /// 根据ID查询
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<T> GetById(int Id)
        {
            var model = await Sqlite.Select<F>().Where(q => q.Id == Id).FirstAsync();
            return mapper.Map<T>(model);
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        public async Task<List<T>> GetAll()
        {
            var models = await Sqlite.Select<F>()
                .ToListAsync();

            return mapper.Map<List<T>>(models);
        }

        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Create(T input)
        {
            input.CreateDate = DateTime.Now;
            var model = mapper.Map<F>(input);
            await Sqlite.Insert(model).ExecuteAffrowsAsync();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task Delete(int Id)
        {
            await Sqlite.Delete<F>(new { Id = Id }).ExecuteAffrowsAsync();
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Update(T input)
        {
            input.UpdateDate = DateTime.Now;
            var model = mapper.Map<F>(input);
            var count = await Sqlite.Update<F>()
                 .SetDto(model)
                 .Where(q => q.Id == input.Id)
                 .ExecuteAffrowsAsync();
        }
    }
}
